﻿using System;
using CRCDesktop.org.h1.crcDesktop.basicClasses;
using CRCDesktop.org.h1.crcDesktop.business;
using CRCDesktop.org.h1.crcDesktop.comunicacao;
using CRCDesktop.org.h1.crcDesktop.util;
using System.Threading;

namespace CRCDesktop
{
    public class Program
    {
        public ControleDispositivo CD { get; set; }

        private volatile ClienteSocket clienteSocket;
        
        private BibliotecaFuncoes b;
        
        private String msgFromServer;
        
        private String msgServer_idCasa;
        private String msgServer_idDispositivo;
        private String msgServer_idPorta;
        private String msgServer_acao;

        //private ThreadListeningSocket listeningSocket;
        //private Thread listening;

        public Config CONFIG { get; set; }
        public ControleConfig CONTROLADOR_CONFIG { get; set; }

        public bool waitingMsg { get; set; }

        public Program()
        {
            this.CD = new ControleDispositivo();
            b = new BibliotecaFuncoes();
            this.CONTROLADOR_CONFIG = new ControleConfig();

            this.CONFIG = this.CONTROLADOR_CONFIG.consultarConfig();

            //Configura as portas do Easy Lab que serão saídas.           
            this.CD.configurarPortaSaida(this.CONFIG.Dispositivos, this.CONFIG.Sensores);


            //Instancia um cliente Socket
            this.clienteSocket = new ClienteSocket();

            //Passa a porta de conexão socket do aqquivo de configuração
            clienteSocket.PortaSocket = CONFIG.SocketPort;

            //Se o EasyLab estiver conectado, conecta com o serverSocket
            if (this.CD.validarConexaoDispositivo())
            {
                //Estabelece conexão com Server Socket
                connecting();
            }

            //Starta a thread responsável por monitarar os sensores da aplicação.
            this.monitorarSensor();

            //Envio de Msg para o server configurar a conexão.
            this.clienteSocket.MsgCliente = "0-" + this.CONFIG.IdCasa;
            this.clienteSocket.onWrite();

            while (true)
            {
                //Fica preso nesse ponto até que uma mensagem seja recebida.
                this.waitingMsg = true;
                while (waitingMsg)
                {
                    if (this.ClienteSocket.isConnected())
                    {

                    this.clienteSocket.onRead();
                        
                        if (!this.clienteSocket.MsgServer.Equals("") && this.clienteSocket.MsgServer != null)
                        {
                            //Sinaliza que houve uma mensagem recebida.
                            this.waitingMsg = false;

                            //Trata a msg recebida.
                            recebeMsg(4);
                        }
                    }
                    else
                    {
                        this.connecting();
                    }
                }

                Console.WriteLine("Mensagem: " + clienteSocket.MsgServer);
                if (!clienteSocket.MsgServer.Equals("OK"))
                {
                    if (msgServer_acao.Equals("1"))
                    {
                        if (this.CD.validarConexaoDispositivo())
                        {
                            Console.WriteLine("Ligou! :-)");
                            this.CD.ligar(int.Parse(msgServer_idCasa),
                                int.Parse(msgServer_idDispositivo), int.Parse(msgServer_idPorta), int.Parse(msgServer_acao));
                            
                           
                        }
                        else
                        {
                            this.clienteSocket.MsgCliente = "DISPOSITIVO_DESCONECTADO";
                        }
                    }
                    else if (msgServer_acao.Equals("0"))
                    {
                        this.CD.desligar(int.Parse(msgServer_idCasa),
                            int.Parse(msgServer_idDispositivo), int.Parse(msgServer_idPorta), int.Parse(msgServer_acao));
                        Console.WriteLine("Desligou :-(");
                       
                    }
                    else
                    {
                        Console.WriteLine("Fudeu :-)");
                    }
                   
                }
            }
        }

        static void Main(string[] args)
        {
            Program p = new Program();
            Console.ReadKey();
        }

        /**
         * Recebe a msg passada pelo Socket e retorna um array com as Strings passadas.
         * */
        public String[] recebeMsg(int tam)
        {
            String[] msgServeFormat = new String[tam];

            //Recebe a msg do Socket com separado "-"
            msgFromServer = ClienteSocket.MsgServer;

            msgServeFormat = b.captureFourString(msgFromServer, 4);

            msgServer_idCasa = msgServeFormat[0];
            msgServer_idDispositivo = msgServeFormat[1];
            msgServer_idPorta = msgServeFormat[2];
            msgServer_acao = msgServeFormat[3];

            return msgServeFormat;
        }

        /*
         *  Este método é responsável por manter a excução da Thread que ouvi o Socket
         */
        public void connecting()
        {
            while (!this.ClienteSocket.isConnected())
            {
                this.ClienteSocket.conect();
            }
        }

        /*
         *  Thread que monitora a execução dos sensores em paralelo com a aplicação.
         * */
        public void monitorarSensor() { 

            ThreadListeningSensor t = new ThreadListeningSensor();
            t.ClienteSocket = this.clienteSocket;
            t.ControleDispositivo = this.CD;

            Thread trd = new Thread(t.listening);
            trd.IsBackground = true;
            trd.Start();
        }

        public void gerarMenuInterativo()
        {
            String inputData;
                ControleDispositivo cd = new ControleDispositivo();
                Boolean execucao = true;

                while (execucao)
                {
                    int searchDevice;
                    searchDevice = cd.searchDispositivo();

                    if (searchDevice == 0)
                    {
                        Console.WriteLine("");
                        Console.WriteLine("+---------------------------------------------------+");
                        Console.WriteLine("|    - Selecione a Operação que deseja Reaalizar -  |");
                        Console.WriteLine("+---------------------------------------------------+");
                        Console.WriteLine("1 - Dispositivos conectados");
                        Console.WriteLine("2 - Ligar Dispositivo");
                        Console.WriteLine("3 - Desligar Dispositivo");
                        Console.WriteLine("4 - Status Dispositivo");
                        Console.WriteLine("5 - Sair");
                        Console.WriteLine(" ");
                        Console.Write(" Operação Selecionada: ");
                        inputData = Console.ReadLine();

                        if (inputData.Equals("1"))
                        {
                            Console.WriteLine("Dispositivos Conectados: " + cd.searchDispositivo());
                        }
                        else if (inputData.Equals("2"))
                        {
                            String inputLigar;

                            Console.WriteLine("");
                            Console.WriteLine(" - Selecione os Dispositivos que deseja LIGAR - ");
                            Console.WriteLine("------------------------------------------------");
                            Console.WriteLine("Porta01 = 1    -   Porta02 = 2   -   Porta03 = 3");
                            Console.WriteLine("Porta04 = 4    -   Porta05 = 5   -   Porta06 = 6");
                            Console.WriteLine("Porta07 = 7    -   Porta08 = 8   -   Porta09 = 9");
                            Console.WriteLine(" ");
                            Console.WriteLine("Dipositivo Selecionado: ");
                            inputLigar = Console.ReadLine();
                            //cd.ligar(int.Parse(inputLigar));
                            Console.WriteLine("Dispositivo ligado com sucesso!");
                        }
                        else if (inputData.Equals("3"))
                        {
                            String inputDesligar;

                            Console.WriteLine("");
                            Console.WriteLine(" - Selecione os Dispositivos que deseja DESLIGAR - ");
                            Console.WriteLine("---------------------------------------------------");
                            Console.WriteLine("Porta01 = 1    -    Porta02 = 2    -    Porta03 = 3");
                            Console.WriteLine("Porta04 = 4    -    Porta05 = 5    -    Porta06 = 6");
                            Console.WriteLine("Porta07 = 7    -    Porta08 = 8    -    Porta09 = 9");
                            Console.WriteLine(" ");
                            Console.WriteLine("Dipositivo Selecionado: ");
                            inputDesligar = Console.ReadLine();
                            //cd.desligar(int.Parse(inputDesligar));
                        }
                        else if (inputData.Equals("4"))
                        {
                            //  Not implemented
                            //int resposta = cd.statusSensor(1, 1, 2, 1);
                            //if (resposta == 1)
                            //{
                            //    Console.Write("Comando realizado");
                            //}
                            //else
                            //{
                            //    Console.Write("comando falhou");
                            //}

                            //Console.Write("Dispositivos Conectados: " + cd.getInPort(0));
                        }
                        else if (inputData.Equals("5"))
                        {
                            execucao = false;
                        }
                    }
                    else
                    {
                        Console.WriteLine("O Dispositivo EasyLab não foi Conectado com Exito!");
                        execucao = false;
                    }
                }
        }

        public ClienteSocket ClienteSocket
        {
            get { return clienteSocket; }
            set { clienteSocket = value; }
        }
    }
}
